#include "File.h"

#include <iostream>
#include <fstream>
#include <streambuf>
#include <utility>

namespace Rz { namespace IO { namespace File {

bool Exists(const String& filename)
{
	FILE* f = fopen(filename.GetCharArray(), "rb");

	if (f == NULL)
	{
		return false;
	}
	else
	{
		fclose(f);
		return true;
	}
}

size_t GetSize(const String& filename)
{
	FILE* f = fopen(filename.GetCharArray(), "rb");

	if (f == NULL)
	{
		return static_cast<size_t>(-1);
	}

	fseek(f, 0, SEEK_END);

	size_t result = ftell(f);

	fclose(f);

	return result;
}

Collections::ByteCollection ReadAllBytes(const String& filename)
{
	Collections::ByteCollection buffer;

	if (!Exists(filename))
	{
		return buffer;
	}

	size_t fileSize = GetSize(filename);

	buffer.Resize(fileSize);
	void* rawBuffer = buffer.GetDataPointer();

	FILE* f = fopen(filename.GetCharArray(), "rb");
	fread(rawBuffer, 1, fileSize, f);
	fclose(f);

	return buffer;
}

String::Collection ReadAllLines(const String& filename)
{
	String::Collection result;

	std::ifstream inFile(filename.Convert<const std::string&>());
	std::string line;

	while (std::getline(inFile, line))
	{
		result.Add(line);
	}

	return result;
}

String ReadAllText(const String& filename)
{
	std::ifstream inFile(filename.GetCharArray());
	std::string str;

	str.reserve(GetSize(filename.GetCharArray()));

	str.assign((std::istreambuf_iterator<char>(inFile)),
		std::istreambuf_iterator<char>());

	return String(std::move(str));
}

} } }
